/*
  author：钱慧敏
  email:1147175965@qq.com
*/

//全局变量，用于操作
var cs_operation={
  onclick_num:0,
  //time:100 [1]设置的用于记录添加菜单花费的时间
};

/*获取cookie*/
function getCookie(name){
  var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
  if(arr=document.cookie.match(reg)) return unescape(arr[2]);
  else return null;
}

/*删除cookie*/
function delCookie(name){
  var exp = new Date();
  exp.setTime(exp.getTime()-1);
  var cval=getCookie(name);
  if(cval!=null) document.cookie= name + "="+cval+";expires="+exp.toGMTString();
}

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    switch(request.etype){
      case "contextmenu_onclick":
        var num=cs_operation.onclick_num++;
        try{
          var ele=document.createElement("div");
          ele.id="RMenus_addon_contextmenu_onclick_"+num;
          ele.style.display="none";
          document.body.appendChild(ele);
          ele.innerHTML="<div pid=\"RMenus_addon_contextmenu_onclick_"+num+"\" \
          onclick=\"RMenus_addon_contextmenu_onclick_handle(event)\">"+JSON.stringify(request.data)+"</div>"
          ele.children[0].click();
        }
        catch(err){console.log(err);}
        break;
      default:
        break;
    }
  }
);

/*页面中在body标签后添加一个contextmenu事件监听，从而按照顺序，
先执行body中添加的contextmenu事件以进行前期数据处理，再执行这里
的事件，最后再弹出系统的菜单，实现数据的链式处理，用户需要的菜单项在页面中
监听的contextmenu事件处理程序中实现
*/
document.body.addEventListener('contextmenu',
  function(event){
    //获取要添加的右键菜单数据
    var data=null;
    try{data=JSON.parse(document.getElementById("RMenus_addon_contextmenu_data").innerText);}
    catch(err){data=null;}

    //[2]首先清除菜单加载完成标记
    delCookie("is_conextmenu_loaded");
    //[2]document.cookie="is_conextmenu_loaded=0";

    //发送数据到background
    if(data!=null){

      chrome.runtime.sendMessage(
        {etype:"contextmenu",info:data},
        function(response){
          data=null;//置空清除数据内存
          //[1]cs_operation.time=(5*response.time>100?100:5*response.time);
        }
      );
    }
    else{
      /*即便没有配置菜单也必须发送数据到background.js以在background.js中调用
      chrome.contextMenus.removeAll()清除其他页面可能配置的右键菜单*/
      chrome.runtime.sendMessage(
        {etype:"contextmenu",info:[]},
        function(response){
          //[1]cs_operation.time=(5*response.time>100?100:5*response.time);
        }
      );
    }
    /*在这里循环从而阻止立刻弹出系统右键菜单，直到循环结束才弹出系统右键菜单*/

    /*
    模拟线程暂停一段时间，这个方法其实不好，它的时间和添加菜单的时间不完全能匹配,
    for(var i=0;i<20000000;i++){;}
    另外想要通过这里重复循环，借由onMessage返回response重置循环条件终止循环也不可行，因为js单线程的原因，这里循环不结束也
    不会去接收消息
    */

    /*[1]
    我们采取的模拟暂停的方法是循环中系统时间差，策略是循环时间初始设置为cs_operation.time:100ms,
    同时在background.js中计算添加菜单所需的执行时间，通过sendResponse返回所需时间并为cs_operation.time
    设置5倍于所需时间的冗余时间但不超过100ms并以此作为下一次的循环执行时间,当然也许我们可以制定更科学的确定时间的统计方案
    */
    //var time=new Date().getTime();
    //while((new Date().getTime())-time<cs_operation.time){;}

    /*最后一个想法是在这里阻止事件，然后在response中重新触发事件不阻止同时对重触发的时间不组织也不向background.js发送消息,
    但重新触发似乎不能调用系统右键菜单，实现不了*/

    /*另一个思路是菜单在加载context_scripts时同时加载进来不再改变，不同页面菜单用documentUrlPatterns去匹配显示
    在background.js编写添加菜单的管理代码，监听页面关闭事件，页面关闭或者更新时删除url对应的菜单，然后重建
    */

    /*[2]通过共享cookie来结束循环流程,同时当时间超过150ms时也结束循环，
    在我个人的电脑上测试右键事件发生时总带来300K左右内存的消耗,不知道是浏览器原因还是代码有问题*/
    var time=new Date().getTime();
    while(true){
      if(getCookie("is_conextmenu_loaded")==="1" ||
        (new Date().getTime())-time>150 ||
        //虽然时间只会增大，但是考虑到系统时间恰好在过程中重置的可能性，比如系统时间比实际的慢了一天，用户恰好重置了
        (new Date().getTime())<time)
      {
        delCookie("is_conextmenu_loaded");//[2]document.cookie="is_conextmenu_loaded=0";
        break;
      }
    }
    time=null;
  }
);
